1use crate::ext::io::*;
2use crate::types::*;
3use crate::utils::encoding::*;
4use crate::utils::struct_pack::*;
5use anyhow::Result;
6use msg_tool_macro::*;
7use std::any::Any;
8use std::io::{Read, Seek, Write};
9
10pub const PSD_SIGNATURE: &[u8; 4] = b"8BPS";
11pub const IMAGE_RESOURCE_SIGNATURE: &[u8; 4] = b"8BIM";
12pub const LAYER_NAME_SOURCE_SETTING_KEY: &[u8; 4] = b"lnsr";
13pub const LAYER_ID_KEY: &[u8; 4] = b"lyid";
14pub const SECTION_DIVIDER_SETTING_KEY: &[u8; 4] = b"lsct";
15pub const UNICODE_LAYER_KEY: &[u8; 4] = b"luni";
16
17#[derive(Debug, Clone)]
18pub struct UnicodeString(pub String);
19
20impl StructPack for UnicodeString {
21 fn pack<W: Write>(
22 &self,
23 writer: &mut W,
24 big: bool,
25 encoding: Encoding,
26 info: &Option<Box<dyn Any>>,
27 ) -> Result<()> {
28 let encoded: Vec<_> = self.0.encode_utf16().collect();
29 let len = encoded.len() as u32;
30 len.pack(writer, big, encoding, info)?;
31 for c in encoded {
32 c.pack(writer, big, encoding, info)?;
33 }
34 Ok(())
35 }
36}
37
38impl StructUnpack for UnicodeString {
39 fn unpack<R: Read + Seek>(
40 reader: &mut R,
41 big: bool,
42 encoding: Encoding,
43 info: &Option<Box<dyn Any>>,
44 ) -> Result<Self> {
45 let len = u32::unpack(reader, big, encoding, info)?;
46 if len == 0 {
47 return Ok(UnicodeString(String::new()));
48 }
49 let mut encoded: Vec<u16> = Vec::with_capacity(len as usize);
50 for _ in 0..len {
51 let c = u16::unpack(reader, big, encoding, info)?;
52 encoded.push(c);
53 }
54 let string = String::from_utf16(&encoded)
55 .map_err(|e| anyhow::anyhow!("Failed to decode UTF-16 string: {}", e))?;
56 Ok(UnicodeString(string))
57 }
58}
59
60#[derive(Debug, Clone)]
61pub struct PascalString(pub Vec<u8>);
62
63impl StructPack for PascalString {
64 fn pack<W: Write>(
65 &self,
66 writer: &mut W,
67 big: bool,
68 encoding: Encoding,
69 info: &Option<Box<dyn Any>>,
70 ) -> Result<()> {
71 let len = self.0.len() as u8;
72 len.pack(writer, big, encoding, info)?;
73 writer.write_all(&self.0)?;
74 if len % 2 == 0 {
75 writer.write_u8(0)?; }
77 Ok(())
78 }
79}
80
81impl StructUnpack for PascalString {
82 fn unpack<R: Read + Seek>(
83 reader: &mut R,
84 big: bool,
85 encoding: Encoding,
86 info: &Option<Box<dyn Any>>,
87 ) -> Result<Self> {
88 let len = u8::unpack(reader, big, encoding, info)?;
89 let encoded = reader.read_exact_vec(len as usize)?;
90 if len % 2 == 0 {
91 reader.read_u8()?; }
93 Ok(PascalString(encoded))
94 }
95}
96
97#[derive(Debug, Clone)]
98pub struct PascalString4(pub Vec<u8>);
99
100impl StructPack for PascalString4 {
101 fn pack<W: Write>(
102 &self,
103 writer: &mut W,
104 big: bool,
105 encoding: Encoding,
106 info: &Option<Box<dyn Any>>,
107 ) -> Result<()> {
108 let len = self.0.len() as u8;
109 len.pack(writer, big, encoding, info)?;
110 let padding = 4 - (len as usize + 1) % 4;
111 writer.write_all(&self.0)?;
112 if padding != 4 {
113 for _ in 0..padding {
114 writer.write_u8(0)?; }
116 }
117 Ok(())
118 }
119}
120
121impl StructUnpack for PascalString4 {
122 fn unpack<R: Read + Seek>(
123 reader: &mut R,
124 big: bool,
125 encoding: Encoding,
126 info: &Option<Box<dyn Any>>,
127 ) -> Result<Self> {
128 let len = u8::unpack(reader, big, encoding, info)?;
129 let encoded = reader.read_exact_vec(len as usize)?;
130 let padding = 4 - (len as usize + 1) % 4;
131 if padding != 4 {
132 for _ in 0..padding {
133 let pad_byte = reader.read_u8()?;
134 if pad_byte != 0 {
135 return Err(anyhow::anyhow!(
136 "Expected padding byte to be 0, got {}",
137 pad_byte
138 ));
139 }
140 }
141 }
142 Ok(PascalString4(encoded))
143 }
144}
145
146#[derive(Debug, Clone, StructPack, StructUnpack)]
147pub struct PsdHeader {
148 pub signature: [u8; 4],
149 pub version: u16,
150 pub reserved: [u8; 6],
151 pub channels: u16,
152 pub height: u32,
153 pub width: u32,
154 pub depth: u16,
155 pub color_mode: u16,
156}
157
158#[derive(Debug, Clone, StructPack, StructUnpack)]
159pub struct ColorModeData {
160 #[pvec(u32)]
161 pub data: Vec<u8>,
162}
163
164#[derive(Debug, Clone)]
165pub struct ImageResourceSection {
166 pub resources: Vec<ImageResourceBlock>,
167}
168
169impl StructUnpack for ImageResourceSection {
170 fn unpack<R: Read + Seek>(
171 reader: &mut R,
172 big: bool,
173 encoding: Encoding,
174 info: &Option<Box<dyn Any>>,
175 ) -> Result<Self> {
176 let length = u32::unpack(reader, big, encoding, info)?;
177 let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
178 let mut resources = Vec::new();
179 while stream_region.cur_pos() < length as u64 {
180 let resource = ImageResourceBlock::unpack(&mut stream_region, big, encoding, info)?;
181 resources.push(resource);
182 if let Ok(d) = stream_region.peek_u8() {
183 if d == 0 {
184 stream_region.read_u8()?; }
186 }
187 }
188 Ok(ImageResourceSection { resources })
189 }
190}
191
192impl StructPack for ImageResourceSection {
193 fn pack<W: Write>(
194 &self,
195 writer: &mut W,
196 big: bool,
197 encoding: Encoding,
198 info: &Option<Box<dyn Any>>,
199 ) -> Result<()> {
200 let mut mem = MemWriter::new();
201 for resource in &self.resources {
202 resource.pack(&mut mem, big, encoding, info)?;
203 }
205 let data = mem.into_inner();
206 let length = data.len() as u32;
207 length.pack(writer, big, encoding, info)?;
208 writer.write_all(&data)?;
209 Ok(())
210 }
211}
212
213#[derive(Debug, Clone, StructPack, StructUnpack)]
214pub struct ImageResourceBlock {
215 pub signature: [u8; 4],
216 pub resource_id: u16,
217 pub name: PascalString,
218 #[pvec(u32)]
219 pub data: Vec<u8>,
220}
221
222#[derive(Debug, Clone)]
223pub struct LayerAndMaskInfo {
224 pub layer_info: LayerInfo,
225 pub global_layer_mask_info: Option<GlobalLayerMaskInfo>,
226 pub tagged_blocks: Vec<u8>,
227}
228
229impl StructUnpack for LayerAndMaskInfo {
230 fn unpack<R: Read + Seek>(
231 reader: &mut R,
232 big: bool,
233 encoding: Encoding,
234 info: &Option<Box<dyn Any>>,
235 ) -> Result<Self> {
236 let length = u32::unpack(reader, big, encoding, info)?;
237 let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
238 let layer_info = LayerInfo::unpack(&mut stream_region, big, encoding, info)?;
239 let length = u32::unpack(&mut stream_region, big, encoding, info)?;
240 let global_layer_mask_info = if length > 0 {
241 stream_region.seek_relative(-4)?;
242 Some(GlobalLayerMaskInfo::unpack(
243 &mut stream_region,
244 big,
245 encoding,
246 info,
247 )?)
248 } else {
249 None
250 };
251 let mut tagged_blocks = Vec::new();
252 stream_region.read_to_end(&mut tagged_blocks)?;
253 Ok(LayerAndMaskInfo {
254 layer_info,
255 global_layer_mask_info,
256 tagged_blocks,
257 })
258 }
259}
260
261impl StructPack for LayerAndMaskInfo {
262 fn pack<W: Write>(
263 &self,
264 writer: &mut W,
265 big: bool,
266 encoding: Encoding,
267 info: &Option<Box<dyn Any>>,
268 ) -> Result<()> {
269 let mut mem = MemWriter::new();
270 self.layer_info.pack(&mut mem, big, encoding, info)?;
271 if let Some(global_layer_mask_info) = &self.global_layer_mask_info {
272 global_layer_mask_info.pack(&mut mem, big, encoding, info)?;
273 } else {
274 0u32.pack(&mut mem, big, encoding, info)?; }
276 mem.write_all(&self.tagged_blocks)?;
277 let data = mem.into_inner();
278 let length = data.len() as u32;
279 length.pack(writer, big, encoding, info)?;
280 writer.write_all(&data)?;
281 Ok(())
282 }
283}
284
285#[derive(Debug, Clone)]
286pub struct LayerInfo {
287 pub layer_count: i16,
288 pub layer_records: Vec<LayerRecord>,
289 pub channel_image_data: Vec<ChannelImageData>,
290}
291
292impl StructUnpack for LayerInfo {
293 fn unpack<R: Read + Seek>(
294 reader: &mut R,
295 big: bool,
296 encoding: Encoding,
297 info: &Option<Box<dyn Any>>,
298 ) -> Result<Self> {
299 let length = u32::unpack(reader, big, encoding, info)?;
300 let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
301 let layer_count = i16::unpack(&mut stream_region, big, encoding, info)?;
302 let mut layer_records = Vec::new();
303 for _ in 0..layer_count.abs() {
304 let layer_record = LayerRecord::unpack(&mut stream_region, big, encoding, info)?;
305 layer_records.push(layer_record);
306 }
307 let mut channel_image_data = Vec::new();
308 for i in 0..layer_count.abs() {
309 let layer = &layer_records[i as usize];
310 for j in 0..layer.base.channels {
311 let info = Some(Box::new((layer.clone(), j as usize)) as Box<dyn Any>);
312 let data = ChannelImageData::unpack(&mut stream_region, big, encoding, &info)?;
313 channel_image_data.push(data);
314 }
315 }
316 stream_region.seek_to_end()?;
317 Ok(LayerInfo {
318 layer_count,
319 layer_records,
320 channel_image_data,
321 })
322 }
323}
324
325impl StructPack for LayerInfo {
326 fn pack<W: Write>(
327 &self,
328 writer: &mut W,
329 big: bool,
330 encoding: Encoding,
331 info: &Option<Box<dyn Any>>,
332 ) -> Result<()> {
333 let mut mem = MemWriter::new();
334 self.layer_count.pack(&mut mem, big, encoding, info)?;
335 for layer_record in &self.layer_records {
336 layer_record.pack(&mut mem, big, encoding, info)?;
337 }
338 let mut index = 0usize;
339 for i in 0..self.layer_count {
340 let layer = &self.layer_records[i as usize];
341 let info = Some(Box::new(layer.clone()) as Box<dyn Any>);
342 for _ in 0..layer.base.channels {
343 let data = &self.channel_image_data[index];
344 index += 1;
345 data.pack(&mut mem, big, encoding, &info)?;
346 }
347 }
348 let data = mem.into_inner();
349
350 let mut length = data.len() as u32;
352 let need_pad = length % 2 != 0;
353 if need_pad {
354 length += 1;
355 }
356 length.pack(writer, big, encoding, info)?;
357 writer.write_all(&data)?;
358 if need_pad {
359 writer.write_u8(0)?; }
361 Ok(())
362 }
363}
364
365#[derive(Debug, Clone, StructPack, StructUnpack)]
366pub struct LayerRecordBase {
367 pub top: i32,
368 pub left: i32,
369 pub bottom: i32,
370 pub right: i32,
371 pub channels: u16,
372 #[unpack_vec_len(channels)]
373 #[pack_vec_len(self.channels)]
374 pub channel_infos: Vec<ChannelInfo>,
375 pub blend_mode_signature: [u8; 4],
376 pub blend_mode_key: [u8; 4],
377 pub opacity: u8,
378 pub clipping: u8,
379 pub flags: u8,
380 pub filler: u8,
381}
382
383#[derive(Debug, Clone)]
384pub struct LayerRecord {
385 pub base: LayerRecordBase,
386 pub layer_mask: Option<LayerMask>,
387 pub layer_blending_ranges: LayerBlendingRanges,
388 pub layer_name: PascalString4,
389 pub infos: Vec<AdditionalLayerInfo>,
390}
391
392impl LayerRecord {
393 pub fn get_info<'a>(&'a self, key: &[u8; 4]) -> Option<&'a [u8]> {
394 for info in &self.infos {
395 if &info.key == key {
396 return Some(&info.data);
397 }
398 }
399 None
400 }
401
402 pub fn layer_name(&self, encoding: Encoding) -> Result<String> {
403 if let Some(uni) = self.get_info(UNICODE_LAYER_KEY) {
404 let data = UnicodeLayer::unpack(&mut MemReaderRef::new(uni), true, encoding, &None)?;
405 Ok(data.name.0)
406 } else {
407 let s = decode_to_string(encoding, &self.layer_name.0, true)?;
408 Ok(s)
409 }
410 }
411}
412
413impl StructPack for LayerRecord {
414 fn pack<W: Write>(
415 &self,
416 writer: &mut W,
417 big: bool,
418 encoding: Encoding,
419 info: &Option<Box<dyn Any>>,
420 ) -> Result<()> {
421 self.base.pack(writer, big, encoding, info)?;
422 let mut mem = MemWriter::new();
423 if let Some(layer_mask) = &self.layer_mask {
424 layer_mask.pack(&mut mem, big, encoding, info)?;
425 } else {
426 0u32.pack(&mut mem, big, encoding, info)?; }
428 self.layer_blending_ranges
429 .pack(&mut mem, big, encoding, info)?;
430 self.layer_name.pack(&mut mem, big, encoding, info)?;
431 for additional_info in &self.infos {
432 additional_info.pack(&mut mem, big, encoding, info)?;
433 }
434 let data = mem.into_inner();
435 let extra_data_length = data.len() as u32;
436 extra_data_length.pack(writer, big, encoding, info)?;
437 writer.write_all(&data)?;
438 Ok(())
439 }
440}
441
442impl StructUnpack for LayerRecord {
443 fn unpack<R: Read + Seek>(
444 reader: &mut R,
445 big: bool,
446 encoding: Encoding,
447 info: &Option<Box<dyn Any>>,
448 ) -> Result<Self> {
449 let base = LayerRecordBase::unpack(reader, big, encoding, info)?;
450 let extra_data_length = u32::unpack(reader, big, encoding, info)?;
451 let mut stream_region = StreamRegion::with_size(reader, extra_data_length as u64)?;
452 let layer_mask_len = u32::unpack(&mut stream_region, big, encoding, info)?;
453 let layer_mask = if layer_mask_len > 0 {
454 stream_region.seek_relative(-4)?;
455 Some(LayerMask::unpack(&mut stream_region, big, encoding, info)?)
456 } else {
457 None
458 };
459 let layer_blending_ranges =
460 LayerBlendingRanges::unpack(&mut stream_region, big, encoding, info)?;
461 let layer_name = PascalString4::unpack(&mut stream_region, big, encoding, info)?;
462 let mut infos = Vec::new();
463 while stream_region.cur_pos() < extra_data_length as u64 {
464 let additional_info =
465 AdditionalLayerInfo::unpack(&mut stream_region, big, encoding, info)?;
466 infos.push(additional_info);
467 }
468 Ok(LayerRecord {
469 base,
470 layer_mask,
471 layer_blending_ranges,
472 layer_name,
473 infos,
474 })
475 }
476}
477
478#[derive(Debug, Clone)]
479pub struct LayerMask {
480 pub top: i32,
481 pub left: i32,
482 pub bottom: i32,
483 pub right: i32,
484 pub default_color: u8,
485 pub flags: u8,
486 pub mask_parameters: Option<u8>,
487 pub mask_data: Option<Vec<u8>>,
488 pub real_flags: Option<u8>,
489 pub real_user_mask_background: Option<u8>,
490 pub mask_top: Option<i32>,
491 pub mask_left: Option<i32>,
492 pub mask_bottom: Option<i32>,
493 pub mask_right: Option<i32>,
494}
495
496impl StructPack for LayerMask {
497 fn pack<W: Write>(
498 &self,
499 writer: &mut W,
500 big: bool,
501 encoding: Encoding,
502 info: &Option<Box<dyn Any>>,
503 ) -> Result<()> {
504 let mut mem = MemWriter::new();
505 self.top.pack(&mut mem, big, encoding, info)?;
506 self.left.pack(&mut mem, big, encoding, info)?;
507 self.bottom.pack(&mut mem, big, encoding, info)?;
508 self.right.pack(&mut mem, big, encoding, info)?;
509 self.default_color.pack(&mut mem, big, encoding, info)?;
510 self.flags.pack(&mut mem, big, encoding, info)?;
511 if self.flags == 4 {
512 if let Some(mask_parameters) = self.mask_parameters {
513 mask_parameters.pack(&mut mem, big, encoding, info)?;
514 } else {
515 return Err(anyhow::anyhow!(
516 "mask_parameters is required when flags == 4"
517 ));
518 }
519 }
520 if let Some(mask_data) = &self.mask_data {
521 mem.write_all(mask_data)?;
522 }
523 if let Some(real_flags) = self.real_flags {
524 real_flags.pack(&mut mem, big, encoding, info)?;
525 let real_user_mask_background = self
526 .real_user_mask_background
527 .ok_or_else(|| anyhow::anyhow!("real_user_mask_background is required"))?;
528 real_user_mask_background.pack(&mut mem, big, encoding, info)?;
529 let mask_top = self
530 .mask_top
531 .ok_or_else(|| anyhow::anyhow!("mask_top is required"))?;
532 mask_top.pack(&mut mem, big, encoding, info)?;
533 let mask_left = self
534 .mask_left
535 .ok_or_else(|| anyhow::anyhow!("mask_left is required"))?;
536 mask_left.pack(&mut mem, big, encoding, info)?;
537 let mask_bottom = self
538 .mask_bottom
539 .ok_or_else(|| anyhow::anyhow!("mask_bottom is required"))?;
540 mask_bottom.pack(&mut mem, big, encoding, info)?;
541 let mask_right = self
542 .mask_right
543 .ok_or_else(|| anyhow::anyhow!("mask_right is required"))?;
544 mask_right.pack(&mut mem, big, encoding, info)?;
545 } else {
546 if mem.data.len() == 18 {
547 mem.write_u16(0)?; }
549 }
550 let data = mem.into_inner();
551 let length = data.len() as u32;
552 length.pack(writer, big, encoding, info)?;
553 writer.write_all(&data)?;
554 Ok(())
555 }
556}
557
558impl StructUnpack for LayerMask {
559 fn unpack<R: Read + Seek>(
560 reader: &mut R,
561 big: bool,
562 encoding: Encoding,
563 info: &Option<Box<dyn Any>>,
564 ) -> Result<Self> {
565 let length = u32::unpack(reader, big, encoding, info)?;
566 let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
567 let top = i32::unpack(&mut stream_region, big, encoding, info)?;
568 let left = i32::unpack(&mut stream_region, big, encoding, info)?;
569 let bottom = i32::unpack(&mut stream_region, big, encoding, info)?;
570 let right = i32::unpack(&mut stream_region, big, encoding, info)?;
571 let default_color = u8::unpack(&mut stream_region, big, encoding, info)?;
572 let flags = u8::unpack(&mut stream_region, big, encoding, info)?;
573 let mask_parameters = if flags == 4 {
574 Some(u8::unpack(&mut stream_region, big, encoding, info)?)
575 } else {
576 None
577 };
578 let mask_data = if flags == 0 || flags == 2 {
579 Some(stream_region.read_exact_vec(1)?)
580 } else if flags == 1 || flags == 3 {
581 Some(stream_region.read_exact_vec(8)?)
582 } else {
583 None
584 };
585 if length == 20 {
586 let _ = stream_region.read_u16()?; }
588 if stream_region.cur_pos() < length as u64 {
589 let real_flags = u8::unpack(&mut stream_region, big, encoding, info)?;
590 let real_user_mask_background = u8::unpack(&mut stream_region, big, encoding, info)?;
591 let mask_top = i32::unpack(&mut stream_region, big, encoding, info)?;
592 let mask_left = i32::unpack(&mut stream_region, big, encoding, info)?;
593 let mask_bottom = i32::unpack(&mut stream_region, big, encoding, info)?;
594 let mask_right = i32::unpack(&mut stream_region, big, encoding, info)?;
595 stream_region.seek_to_end()?;
596 Ok(LayerMask {
597 top,
598 left,
599 bottom,
600 right,
601 default_color,
602 flags,
603 mask_parameters,
604 mask_data,
605 real_flags: Some(real_flags),
606 real_user_mask_background: Some(real_user_mask_background),
607 mask_top: Some(mask_top),
608 mask_left: Some(mask_left),
609 mask_bottom: Some(mask_bottom),
610 mask_right: Some(mask_right),
611 })
612 } else {
613 stream_region.seek_to_end()?;
614 Ok(LayerMask {
615 top,
616 left,
617 bottom,
618 right,
619 default_color,
620 flags,
621 mask_parameters,
622 mask_data,
623 real_flags: None,
624 real_user_mask_background: None,
625 mask_top: None,
626 mask_left: None,
627 mask_bottom: None,
628 mask_right: None,
629 })
630 }
631 }
632}
633
634#[derive(Debug, Clone, StructPack, StructUnpack)]
635pub struct ChannelInfo {
636 pub channel_id: i16,
637 pub length: u32,
638}
639
640#[derive(Debug, Clone)]
641pub struct LayerBlendingRanges {
642 pub gray_blend_source: u32,
643 pub gray_blend_dest: u32,
644 pub channel_ranges: Vec<ChannelRange>,
645}
646
647impl StructUnpack for LayerBlendingRanges {
648 fn unpack<R: Read + Seek>(
649 reader: &mut R,
650 big: bool,
651 encoding: Encoding,
652 info: &Option<Box<dyn Any>>,
653 ) -> Result<Self> {
654 let total_length = u32::unpack(reader, big, encoding, info)?;
655 let mut stream_region = StreamRegion::with_size(reader, total_length as u64)?;
656 let gray_blend_source = u32::unpack(&mut stream_region, big, encoding, info)?;
657 let gray_blend_dest = u32::unpack(&mut stream_region, big, encoding, info)?;
658 let mut channel_ranges = Vec::new();
659 while stream_region.cur_pos() < total_length as u64 {
660 let channel_range = ChannelRange::unpack(&mut stream_region, big, encoding, info)?;
661 channel_ranges.push(channel_range);
662 }
663 Ok(LayerBlendingRanges {
664 gray_blend_source,
665 gray_blend_dest,
666 channel_ranges,
667 })
668 }
669}
670
671impl StructPack for LayerBlendingRanges {
672 fn pack<W: Write>(
673 &self,
674 writer: &mut W,
675 big: bool,
676 encoding: Encoding,
677 info: &Option<Box<dyn Any>>,
678 ) -> Result<()> {
679 let mut mem = MemWriter::new();
680 self.gray_blend_source.pack(&mut mem, big, encoding, info)?;
681 self.gray_blend_dest.pack(&mut mem, big, encoding, info)?;
682 for channel_range in &self.channel_ranges {
683 channel_range.pack(&mut mem, big, encoding, info)?;
684 }
685 let data = mem.into_inner();
686 let total_length = data.len() as u32;
687 total_length.pack(writer, big, encoding, info)?;
688 writer.write_all(&data)?;
689 Ok(())
690 }
691}
692
693#[derive(Debug, Clone, StructPack, StructUnpack)]
694pub struct ChannelRange {
695 pub source_range: u32,
696 pub dest_range: u32,
697}
698
699#[derive(Debug, Clone)]
700pub struct AdditionalLayerInfo {
701 pub signature: [u8; 4],
702 pub key: [u8; 4],
703 pub data: Vec<u8>,
704}
705
706impl StructUnpack for AdditionalLayerInfo {
707 fn unpack<R: Read + Seek>(
708 reader: &mut R,
709 big: bool,
710 encoding: Encoding,
711 info: &Option<Box<dyn Any>>,
712 ) -> Result<Self> {
713 let signature = <[u8; 4]>::unpack(reader, big, encoding, info)?;
714 let key = <[u8; 4]>::unpack(reader, big, encoding, info)?;
715 let length = u32::unpack(reader, big, encoding, info)?;
716 let data = reader.read_exact_vec(length as usize)?;
717 Ok(AdditionalLayerInfo {
718 signature,
719 key,
720 data,
721 })
722 }
723}
724
725impl StructPack for AdditionalLayerInfo {
726 fn pack<W: Write>(
727 &self,
728 writer: &mut W,
729 big: bool,
730 encoding: Encoding,
731 info: &Option<Box<dyn Any>>,
732 ) -> Result<()> {
733 self.signature.pack(writer, big, encoding, info)?;
734 self.key.pack(writer, big, encoding, info)?;
735 let mut length = self.data.len() as u32;
736 let need_pad = length % 2 != 0;
737 if need_pad {
738 length += 1;
739 }
740 length.pack(writer, big, encoding, info)?;
741 writer.write_all(&self.data)?;
742 if need_pad {
743 writer.write_u8(0)?; }
745 Ok(())
746 }
747}
748
749#[derive(Debug, Clone)]
750pub struct ChannelImageData {
751 pub compression: u16,
752 pub image_data: Vec<u8>,
753}
754
755fn get_layer_info(info: &Option<Box<dyn Any>>) -> Result<&LayerRecord> {
756 if let Some(boxed) = info {
757 if let Some(layer_record) = boxed.downcast_ref::<LayerRecord>() {
758 return Ok(layer_record);
759 }
760 }
761 Err(anyhow::anyhow!(
762 "LayerRecord info is required for ChannelImageData unpacking"
763 ))
764}
765
766fn get_layer_info_with_channel_index(info: &Option<Box<dyn Any>>) -> Result<&(LayerRecord, usize)> {
767 if let Some(boxed) = info {
768 if let Some(layer_info) = boxed.downcast_ref::<(LayerRecord, usize)>() {
769 return Ok(layer_info);
770 }
771 }
772 Err(anyhow::anyhow!(
773 "LayerRecord and channel index info is required for ChannelImageData unpacking"
774 ))
775}
776
777impl StructUnpack for ChannelImageData {
778 fn unpack<R: Read + Seek>(
779 reader: &mut R,
780 big: bool,
781 encoding: Encoding,
782 info: &Option<Box<dyn Any>>,
783 ) -> Result<Self> {
784 let (layer, idx) = get_layer_info_with_channel_index(info)?;
785 let layer_len = layer
786 .base
787 .channel_infos
788 .get(*idx)
789 .ok_or_else(|| anyhow::anyhow!("Channel index {} out of bounds for layer", idx))?
790 .length;
791 let mut stream_region = StreamRegion::with_size(reader, layer_len as u64)?;
792 let compression = u16::unpack(&mut stream_region, big, encoding, info)?;
793 let mut image_data = Vec::new();
794 stream_region.read_to_end(&mut image_data)?;
795 Ok(ChannelImageData {
796 compression,
797 image_data,
798 })
799 }
800}
801
802impl StructPack for ChannelImageData {
803 fn pack<W: Write>(
804 &self,
805 writer: &mut W,
806 big: bool,
807 encoding: Encoding,
808 info: &Option<Box<dyn Any>>,
809 ) -> Result<()> {
810 self.compression.pack(writer, big, encoding, info)?;
811 if self.compression == 0 {
812 let layer_info = get_layer_info(info)?;
813 let expected_len = (layer_info.base.bottom - layer_info.base.top) as usize
814 * (layer_info.base.right - layer_info.base.left) as usize;
815 if self.image_data.len() != expected_len {
816 return Err(anyhow::anyhow!(
817 "Channel image data length does not match expected size"
818 ));
819 }
820 }
821 writer.write_all(&self.image_data)?;
822 Ok(())
823 }
824}
825
826#[derive(Debug, Clone)]
827pub struct GlobalLayerMaskInfo {
828 pub overlays_color_space: u16,
829 pub overlays_color_components: [u16; 4],
830 pub opacity: u16,
831 pub kind: u8,
832 pub filler: Vec<u8>,
833}
834
835impl StructUnpack for GlobalLayerMaskInfo {
836 fn unpack<R: Read + Seek>(
837 reader: &mut R,
838 big: bool,
839 encoding: Encoding,
840 info: &Option<Box<dyn Any>>,
841 ) -> Result<Self> {
842 let length = u32::unpack(reader, big, encoding, info)?;
843 let mut stream_region = StreamRegion::with_size(reader, length as u64)?;
844 let overlays_color_space = u16::unpack(&mut stream_region, big, encoding, info)?;
845 let mut overlays_color_components = [0u16; 4];
846 for i in 0..4 {
847 overlays_color_components[i] = u16::unpack(&mut stream_region, big, encoding, info)?;
848 }
849 let opacity = u16::unpack(&mut stream_region, big, encoding, info)?;
850 let kind = u8::unpack(&mut stream_region, big, encoding, info)?;
851 let filler_length = length as usize - 2 - (4 * 2) - 2 - 1;
852 let mut filler = vec![0u8; filler_length];
853 stream_region.read_exact(&mut filler)?;
854 stream_region.seek_to_end()?;
855 Ok(GlobalLayerMaskInfo {
856 overlays_color_space,
857 overlays_color_components,
858 opacity,
859 kind,
860 filler,
861 })
862 }
863}
864
865impl StructPack for GlobalLayerMaskInfo {
866 fn pack<W: Write>(
867 &self,
868 writer: &mut W,
869 big: bool,
870 encoding: Encoding,
871 info: &Option<Box<dyn Any>>,
872 ) -> Result<()> {
873 let mut mem = MemWriter::new();
874 self.overlays_color_space
875 .pack(&mut mem, big, encoding, info)?;
876 for component in &self.overlays_color_components {
877 component.pack(&mut mem, big, encoding, info)?;
878 }
879 self.opacity.pack(&mut mem, big, encoding, info)?;
880 self.kind.pack(&mut mem, big, encoding, info)?;
881 mem.write_all(&self.filler)?;
882 let data = mem.into_inner();
883 let length = data.len() as u32;
884 length.pack(writer, big, encoding, info)?;
885 writer.write_all(&data)?;
886 Ok(())
887 }
888}
889
890#[derive(Debug, Clone)]
891pub struct ImageDataSection {
892 pub compression: u16,
893 pub image_data: Vec<u8>,
894}
895
896fn get_psd_header(info: &Option<Box<dyn Any>>) -> Result<&PsdHeader> {
897 if let Some(boxed) = info {
898 if let Some(psd_header) = boxed.downcast_ref::<PsdHeader>() {
899 return Ok(psd_header);
900 }
901 }
902 Err(anyhow::anyhow!("PsdHeader info is required"))
903}
904
905impl StructUnpack for ImageDataSection {
906 fn unpack<R: Read + Seek>(
907 reader: &mut R,
908 big: bool,
909 encoding: Encoding,
910 info: &Option<Box<dyn Any>>,
911 ) -> Result<Self> {
912 let compression = u16::unpack(reader, big, encoding, info)?;
913 let mut image_data = Vec::new();
914 reader.read_to_end(&mut image_data)?;
915 Ok(ImageDataSection {
916 compression,
917 image_data,
918 })
919 }
920}
921
922impl StructPack for ImageDataSection {
923 fn pack<W: Write>(
924 &self,
925 writer: &mut W,
926 big: bool,
927 encoding: Encoding,
928 info: &Option<Box<dyn Any>>,
929 ) -> Result<()> {
930 self.compression.pack(writer, big, encoding, info)?;
931 if self.compression == 0 {
932 let psd_header = get_psd_header(info)?;
933 let expected_len = psd_header.channels as usize
934 * psd_header.height as usize
935 * psd_header.width as usize
936 * psd_header.depth as usize
937 / 8;
938 if self.image_data.len() != expected_len {
939 return Err(anyhow::anyhow!(
940 "Image data length does not match expected size"
941 ));
942 }
943 }
944 writer.write_all(&self.image_data)?;
945 Ok(())
946 }
947}
948
949#[derive(Debug)]
950pub struct PsdFile {
951 pub header: PsdHeader,
952 pub color_mode_data: ColorModeData,
953 pub image_resource: ImageResourceSection,
954 pub layer_and_mask_info: LayerAndMaskInfo,
955 pub image_data: ImageDataSection,
956}
957
958impl StructPack for PsdFile {
959 fn pack<W: Write>(
960 &self,
961 writer: &mut W,
962 big: bool,
963 encoding: Encoding,
964 _info: &Option<Box<dyn Any>>,
965 ) -> Result<()> {
966 let psd_info = Some(Box::new(self.header.clone()) as Box<dyn Any>);
967 self.header.pack(writer, big, encoding, &psd_info)?;
968 self.color_mode_data
969 .pack(writer, big, encoding, &psd_info)?;
970 self.image_resource.pack(writer, big, encoding, &psd_info)?;
971 self.layer_and_mask_info
972 .pack(writer, big, encoding, &psd_info)?;
973 self.image_data.pack(writer, big, encoding, &psd_info)?;
974 Ok(())
975 }
976}
977
978impl StructUnpack for PsdFile {
979 fn unpack<R: Read + Seek>(
980 reader: &mut R,
981 big: bool,
982 encoding: Encoding,
983 info: &Option<Box<dyn Any>>,
984 ) -> Result<Self> {
985 let header = PsdHeader::unpack(reader, big, encoding, info)?;
986 let psd_info = Some(Box::new(header.clone()) as Box<dyn Any>);
987 let color_mode_data = ColorModeData::unpack(reader, big, encoding, &psd_info)?;
988 let image_resource = ImageResourceSection::unpack(reader, big, encoding, &psd_info)?;
989 let layer_and_mask_info = LayerAndMaskInfo::unpack(reader, big, encoding, &psd_info)?;
990 let image_data = ImageDataSection::unpack(reader, big, encoding, &psd_info)?;
991 Ok(PsdFile {
992 header,
993 color_mode_data,
994 image_resource,
995 layer_and_mask_info,
996 image_data,
997 })
998 }
999}
1000
1001impl PsdFile {
1002 pub fn layer_count(&self) -> usize {
1003 self.layer_and_mask_info.layer_info.layer_count.abs() as usize
1004 }
1005}
1006
1007#[derive(Debug, Clone, StructPack, StructUnpack)]
1008pub struct SectionDividerSetting {
1009 pub typ: u32,
1010 }
1012
1013#[derive(Debug, Clone, StructPack, StructUnpack)]
1014pub struct UnicodeLayer {
1015 pub name: UnicodeString,
1016}
1017
1018#[derive(Debug, Clone, StructPack, StructUnpack)]
1019pub struct LayerID {
1020 pub id: u32,
1022}
1023
1024#[derive(Debug, Clone, StructPack, StructUnpack)]
1025pub struct LayerNameSourceSetting {
1026 pub id: i32,
1028}